package cn.dansj.common.utils.jdbc;

import cn.dansj.common.utils.enums.GlobalEnv;
import cn.dansj.common.utils.json.JSONUtils;
import cn.dansj.common.utils.json.JSONObject;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.util.ClassUtils;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Map;

public class ColumnRowMapper<T> implements RowMapper<T> {
    private Class<?> requiredType = Map.class;

    public ColumnRowMapper() {
    }

    public ColumnRowMapper(Class<T> requiredType) {
        if (requiredType != Object.class) {
            this.requiredType = ClassUtils.resolvePrimitiveIfNecessary(requiredType);
        }
    }

    @Override
    @SuppressWarnings("unchecked")
    public T mapRow(ResultSet rs, int rowNum) throws SQLException {
        ResultSetMetaData rsmd = rs.getMetaData();
        int columnCount = rsmd.getColumnCount();
        JSONObject mapOfColumnValues = new JSONObject(columnCount);
        for (int i = 1; i <= columnCount; i++) {
            String column = JdbcUtils.lookupColumnName(rsmd, i);
            if (column.equalsIgnoreCase(GlobalEnv.SqlPageRowNumberColumn)) {
                continue;
            }
            mapOfColumnValues.putIfAbsent(getColumnKey(column), getColumnValue(rs, i));
        }
        return (T) JSONUtils.toObj(mapOfColumnValues, requiredType);
    }

    /**
     * 转成小写格式
     */
    protected String getColumnKey(String columnName) {
        return columnName.toLowerCase();
    }

    /**
     * 获取每一个单元格的数据,根据数据类型转换显示格式
     */
    protected Object getColumnValue(ResultSet rs, int index) throws SQLException {
        Object resultSetValue = JdbcUtils.getResultSetValue(rs, index);
        /*转换LocalDateTime的显示格式,去掉中间的T*/
        if (resultSetValue instanceof LocalDateTime) {
            resultSetValue = ((LocalDateTime) resultSetValue).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        }

        return resultSetValue;
    }
}
